package com.neoCalf.neoCommon.utils;

import com.neoCalf.neoCommon.enums.ResultCode;
import com.neoCalf.neoCommon.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;

import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Optional;


/**
 * 写一个MD5算法,运行结果与MySQL的md5()函数相同
 * 将明文密码转成MD5密码
 * 123456->e10adc3949ba59abbe56e057f20f883e
 */
@Slf4j
public class Md5Util {
    /**
     * 将明文密码转成MD5密码
     */
    public static String encodeByMd5(String string) {
        try {
            //Java中MessageDigest类封装了MD5和SHA算法
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            //调用MD5算法，即返回16个byte类型的值
            byte[] byteArray = md5.digest(string.getBytes());
            //注意：MessageDigest只能将String转成byte[]，接下来的事情，由我们程序员来完成
            return byteArrayToHexString(byteArray);
        } catch (Exception e) {
            log.error("异常: ", e);
            return "fc5ae9ce578fa6bff964d0052e91b2d143";
        }
    }

    /**
     * 将byte[]转在16进制字符串
     */
    private static String byteArrayToHexString(byte[] byteArray) {
        StringBuilder sb = new StringBuilder();
        //遍历
        for (byte b : byteArray) {//16次
            //取出每一个byte类型，进行转换
            String hex = byteToHexString(b);
            //将转换后的值放入StringBuffer中
            sb.append(hex);
        }
        return sb.toString();
    }

    /**
     * 将byte转成16进制字符串
     */
    private static String byteToHexString(byte b) {//-31转成e1，10转成0a，。。。
        //将byte类型赋给int类型
        int n = b;
        //如果n是负数
        if (n < 0) {
            //转正数
            //-31的16进制数，等价于求225的16进制数
            n = 256 + n;
        }
        //商(14)，数组的下标
        int d1 = n / 16;
        //余(1)，数组的下标
        int d2 = n % 16;
        //通过下标取值
        return hex[d1] + hex[d2];
    }

    public static String Md5Method(String[] args) {
        Optional<String> reduce = Arrays.stream(args).sorted().reduce((a, b) -> a + b);
        if (reduce.isPresent()) {
            return encodeByMd5(reduce.get());
        }
        throw new BusinessException(ResultCode.BusinessError);
    }

    private static final String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static void main(String[] args) {
        String g11942322362 = Md5Method(new String[]{"G15200011049"});
        System.out.println(g11942322362);
    }
}
